<template>
  <div class="clamp-text-container">
    <div ref="textWrapper" class="text-wrapper">
      <div
        ref="textRef"
        class="clamp-text"
        :class="{ 'clamp-text--clamped': isClamped && !expanded }"
        :style="{ '-webkit-line-clamp': expanded ? 'unset' : maxLines }"
      >
        <slot>{{ text }}</slot>
      </div>
      <div v-if="isClamped || expanded" class="btn-line">
        <button class="clamp-text-toggle" @click="toggleExpand">
          <span>{{ expanded ? "收起" : "展开" }}</span>
          <el-icon v-if="expanded"><ArrowUp /></el-icon>
          <el-icon v-else><ArrowDown /></el-icon>
        </button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, watch, nextTick } from "vue"

const props = defineProps({
  text: { type: String, default: "" },
  maxLines: { type: Number, default: 3 }
})

const textRef = ref(null)
const textWrapper = ref(null)
const isClamped = ref(false)
const expanded = ref(false)
const isManualToggle = ref(false) // 新增标志位

// 检测文本是否被截断
const checkClamped = async () => {
  if (isManualToggle.value) {
    isManualToggle.value = false
    return
  }

  await nextTick()
  if (!textRef.value) return
  isClamped.value = textRef.value.scrollHeight > textRef.value.clientHeight
}

const toggleExpand = () => {
  isManualToggle.value = true
  expanded.value = !expanded.value
}

onMounted(() => {
  checkClamped()
  const resizeObserver = new ResizeObserver(checkClamped)
  if (textWrapper.value) resizeObserver.observe(textWrapper.value)
})

watch(() => props.text, checkClamped)
</script>

<style scoped>
.clamp-text-container {
  width: 100%;
}

.text-wrapper {
  /* position: relative; */
  /* display: inline-block; */
  /* width: 100%; */
}

.clamp-text {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  word-break: break-word;
  line-height: 1.5;
}

.clamp-text--clamped {
  -webkit-line-clamp: v-bind(maxLines);
}
.btn-line {
  display: flex;
  justify-content: flex-end;
  align-items: center;
}
.clamp-text-toggle {
  display: flex;
  align-items: center;
  color: #1890ff;
  background: none;
  border: none;
  cursor: pointer;
  font-size: inherit;
  z-index: 1;
}

.clamp-text-toggle:hover {
  color: #40a9ff;
}

.clamp-text-toggle.expanded {
  position: static;
  display: inline-block;
  margin-left: 4px;
}
</style>
